package ace.cmp.core.exception;

import ace.cmp.core.enums.SystemCodeEnum;
import java.util.HashMap;
import java.util.Map;
import lombok.AccessLevel;
import lombok.Getter;

/**
 * @author Caspar 业务异常
 */
public class BusinessException extends RuntimeException {

  @Getter(AccessLevel.PUBLIC)
  private Integer code = SystemCodeEnum.BUSINESS_EXCEPTION.getCode();

  @Getter(AccessLevel.PUBLIC)
  private final Map<String, Object> extras = new HashMap<>();

  public BusinessException() {}

  public BusinessException(String message) {
    super(message);
  }

  public BusinessException(String message, Throwable throwable) {
    super(message, throwable);
  }

  public BusinessException(Integer code, String message) {
    super(message);
    this.code = code;
  }

  public BusinessException(Integer code, String message, Throwable throwable) {
    super(message, throwable);
    this.code = code;
  }

  public BusinessException(
      Integer code, String message, Map<String, Object> extras, Throwable throwable) {
    super(message, throwable);
    this.code = code;
    this.extras.putAll(extras);
  }

  public BusinessException(Integer code, String message, Map<String, Object> extras) {
    super(message);
    this.code = code;
    this.extras.putAll(extras);
  }

  public BusinessException(Integer code, Map<String, Object> extras) {
    super(SystemCodeEnum.BUSINESS_EXCEPTION.getDesc());
    this.code = code;
    this.extras.putAll(extras);
  }

  public BusinessException(String message, Map<String, Object> extras) {
    super(message);
    this.extras.putAll(extras);
  }

  public BusinessException(Integer code, Throwable throwable) {
    super(throwable);
    this.code = code;
  }

  public BusinessException(Throwable throwable) {
    super(throwable);
  }

  public static BusinessException create(String messageTemplate, String... args) {
    String message = String.format(messageTemplate, args);
    return new BusinessException(message);
  }

  public static BusinessException createWithCode(
      Integer code, String messageTemplate, String... args) {
    String message = String.format(messageTemplate, args);
    return new BusinessException(code, message);
  }

  public static BusinessException create(
      Integer code, Throwable throwable, String messageTemplate, String... args) {
    String message = String.format(messageTemplate, args);
    return new BusinessException(code, message, throwable);
  }
}
